package com.ybw.redis.distributed.lock.service;

import java.util.concurrent.TimeUnit;

import org.redisson.api.RLock;

/**
 * 分布式锁
 *
 * @author geoffrey
 * @version V1.0
 * @className DistributedLockerService
 * @date 2022/3/27
 **/
public interface DistributedLockerService {

    /**
     * 加锁
     * 如果不设置，默认的生存时间是30s，启动看门狗
     *
     * @param lockKey
     * @methodName: lock
     * @return: org.redisson.api.RLock
     * @author: geoffrey
     * @date: 2022/3/26
     **/
    RLock lock(String lockKey);

    /**
     * 带超时的锁
     * timeout秒以后自动解锁，不启动看门狗，锁到期不续
     *
     * @param lockKey
     * @param timeout 超时时间   单位：秒
     * @methodName: lock
     * @return: org.redisson.api.RLock
     * @author: geoffrey
     * @date: 2022/3/26
     **/
    RLock lock(String lockKey, int timeout);

    /**
     * 带超时的锁
     * timeout时间以后自动解锁，不启动看门狗，锁到期不续
     *
     * @param lockKey
     * @param unit    时间单位
     * @param timeout 超时时间
     * @methodName: lock
     * @return: org.redisson.api.RLock
     * @author: geoffrey
     * @date: 2022/3/26
     **/
    RLock lock(String lockKey, TimeUnit unit, int timeout);

    /**
     * 尝试获取锁
     *
     * @param lockKey
     * @param unit      时间单位
     * @param waitTime  尝试加锁最多等待最多等待时间
     * @param leaseTime 在leaseTime时间后锁就自动失效，不会去续期；如果是 -1 ，就表示 使用看门狗的默认值。
     *                  获取锁成功的持有时间，过期自动解锁
     *                  如果设置了leaseTimeout，看门狗就会自动失效了
     *                  redisson于是提供了这个看门狗，如果还没执行完毕，监听到这个客户端A的线程还持有锁，就去续期，默认是  LockWatchdogTimeout/ 3 即 10 秒监听一次，如果还持有，就不断的延长锁的有效期(重新给锁设置过期时间，30s)
     * @methodName: tryLock
     * @return: boolean
     * @author: geoffrey
     * @date: 2022/3/26
     **/
    boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime);

    /**
     * 尝试获取锁
     *
     * @param lockKey
     * @param unit
     * @param waitTime
     * @methodName: tryLock
     * @return: boolean
     * @author: ybw
     * @date: 2023/3/29
     **/
    boolean tryLock(String lockKey, TimeUnit unit, int waitTime);

    /**
     * 释放锁
     *
     * @param lockKey
     * @methodName: unlock
     * @return: void
     * @author: geoffrey
     * @date: 2022/3/26
     **/
    void unlock(String lockKey);

    /**
     * 释放锁
     *
     * @param lock
     * @methodName: unlock
     * @return: void
     * @author: geoffrey
     * @date: 2022/3/26
     **/
    void unlock(RLock lock);

    /**
     * 检验该锁是否被线程使用，如果被使用返回True
     *
     * @methodName: isLocked
     * @return: boolean
     * @author: geoffrey
     * @date: 2022/3/27
     **/
    boolean isLocked(RLock lock);

    /**
     *
     */
    /**
     * 检查当前线程是否获得此锁（这个和上面的区别就是该方法可以判断是否当前线程获得此锁，而不是此锁是否被线程占有）
     * 这个比上面那个实用
     *
     * @methodName: isHeldByCurrentThread
     * @return: boolean
     * @author: geoffrey
     * @date: 2022/3/27
     **/
    boolean isHeldByCurrentThread(RLock lock);
}